


//SDL_WM_SetCaption ("SDL MultiMedia Application", NULL);

// Archivo: Ralph.cpp
// Trabajo Practico Nº 4
//
// Integrantes			DNI
//
// Broqua Fernando		34476433
// Flores Marcelo		34767349
// Lancha Damián		31732856
// Tarsitano Ariel		34784113
//
// Primera Entrega.

#include "cliente.h"
#include "config.h"

#define APP_CONFIG	"/tmp/archivoconfiguracion"


/////////////////// Esperar una tecla para continuar ////////////////////////////////////////
int SDLA_esperarTecla() {
   SDL_Event suceso;

  /* Imitacion de "getch()" para SDL */
  while (1) {                            /* Repetimos indefinidamente */
    while (SDL_PollEvent(&suceso)) {     /* Comprobamos sucesos */
        if (suceso.type == SDL_KEYUP)  /* Si es tecla pulsada */
          return suceso.key.keysym.sym;  /* La devolvermos */
      }
  }
  return 0;

}

//////////////////// Manejador de Eventos ////////////////////////////////
void procesarEventosSDL(destinoSprite m[53][10],map<int, int> contr,bool *estoyVivo,unsigned short int *miIdJugador,char miNombre[10])
{

 SDL_Event event;
 //SDL_PollEvent(&event); //Encola los eventos
 SDL_WaitEvent(&event); //Se bloquea esperando un evento

 switch(event.type)
 {
   case SDL_QUIT:
       procesarEventoSDLQuit();
     break;

   case SDL_KEYDOWN:
      {
       procesarEventoSDLKeyDown(&event,m,contr,estoyVivo,miIdJugador,miNombre);
       break;
      }
 }
}

/////////////////// Maneja tecla Escape ////////////////////////////
void procesarEventoSDLQuit(void)
{
  SDL_Quit();
  exit(1);
}

/////////////////// Maneja presion de una tecla //////////////////////////////
void procesarEventoSDLKeyDown(SDL_Event* event,destinoSprite m[53][10],map<int, int> contr,bool *estoyVivo,unsigned short int *miIdJugador,char miNombre[10])
{

 //se fija si toco escape
 if(event->key.keysym.sym == SDLK_ESCAPE)
 {
                //Salir torneo
    	    	accion accion;
    	    	accion.id_accion=ACC_ESCAPE;
    	    	accion.id_entidad=0;
    	    	accion.mov_x=0;
    	    	accion.mov_y=0;
    	    	unsigned short int tramo=0;
    	    	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);

 }

if(*estoyVivo==true)
{
 switch( contr[event->key.keysym.sym] )
 {

    case ACCION1: //tecla x
                  {
    	        //struct accion
    	    	//  {
    	    	//     unsigned int id_accion; //ACC_MOVER
    	    	//     unsigned int id_entidad; //identificado del elemento a mover
    	    	//     unsigned int mov_x; //offset x
    	    	//     unsigned int mov_y; //offset y
    	    	//  };


    	       //Simulacion de mensajes enviados por el Servidor de Partida

    	  	  	   //Crear Torta
    	        	accion accion;
    	        	accion.id_accion=ACC_CREAR_TORTA;
    	        	accion.id_entidad=ID_VIDRIO13;
    	        	accion.mov_x=0;
    	        	accion.mov_y=0;
    	        	unsigned short int tramo=obtenerTramo(m);
    	        	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);

  	  	       //Crear Ave
	         /*	accion accion;
	        	accion.id_accion=ACC_CREAR_AVE;
	        	accion.id_entidad=0;
	        	accion.mov_x=300;
	        	accion.mov_y=300;
	        	unsigned short int tramo=0;
	        	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);*/

    	        //Crear Ladrillo
    	    /*	accion accion;
    	    	accion.id_accion=ACC_CREAR_LAD;
    	    	accion.id_entidad=ID_LADRILLO0;
    	    	accion.mov_x=100;
    	    	accion.mov_y=100;
    	    	unsigned short int tramo=0;
    	    	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);*/

    	       //Restar vida
    	    /*	accion accion;
    	    	accion.id_accion=ACC_REST_VIDA;
    	    	accion.id_entidad=ID_FELIX1;
    	    	accion.mov_x=0;
    	    	accion.mov_y=0;
    	    	unsigned short int tramo=0;
    	    	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);*/

    	        //Murio uno de los Felix
    	        /*accion accion;
    	    	accion.id_accion=ACC_MORIR;
    	    	accion.id_entidad=ID_FELIX1;
    	    	accion.mov_x=0;
    	    	accion.mov_y=0;
    	    	unsigned short int tramo=0;
    	    	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
                */


                  break;}
    case ACCION2:  //tecla c
                 {
    	        //struct accion
    	    	//  {
    	    	//     unsigned int id_accion; //ACC_MOVER
    	    	//     unsigned int id_entidad; //identificado del elemento a mover
    	    	//     unsigned int mov_x; //offset x
    	    	//     unsigned int mov_y; //offset y
    	    	//  };


    	       //Simulacion de mensajes enviados por el Servidor de Partida

    	  	  	   //Eliminar Torta
    	      /*  	accion accion;
    	        	accion.id_accion=ACC_ELIM_TORTA;
    	        	accion.id_entidad=ID_VIDRIO0;
    	        	accion.mov_x=0;
    	        	accion.mov_y=0;
    	        	unsigned short int tramo=0;
    	        	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);*/

 	       //Eliminar Ave
      	   /*accion accion;
      		accion.id_accion=ACC_ELIM_AVE;
      		unsigned short int tramo=0;
      		procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);*/

	       //Eliminar Ladrillo
   	        accion accion;
   		    accion.id_accion=ACC_ELIM_LAD;
   		    accion.id_entidad=ID_LADRILLO0;
   		    unsigned short int tramo=0;
   		    procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);

               //Murio uno de los Felix
              /*  accion accion;
                accion.id_accion=ACC_MORIR;
                accion.id_entidad=ID_FELIX2;
                accion.mov_x=0;
                accion.mov_y=0;
                unsigned short int tramo=0;
                procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
                */

                  break;}


    case SCROLLUP:  {int scrollV=333;
                     //Desplazo el dibujo verticalmente
                     for(int i=0; i<=41;i++)
                       for(int j=0;j<=9;j++)
                         m[i][j].destino.y+=scrollV;


                    if(m[42][4].destino.y>14)
                      {
                       m[42][4].destino.y-= 9;
                       m[43][7].destino.y-= 111*3;
                      }
                    if(m[42][5].destino.y>14)
                      {
                       m[42][5].destino.y-= 9;
                       m[43][8].destino.y-= 111*3;
                      }
                     break;}
    case SCROLLDOWN:  {int scrollV=-333;
                     //Desplazo el dibujo verticalmente
                     for(int i=0; i<=41;i++)
                       for(int j=0;j<=9;j++)
                         m[i][j].destino.y+=scrollV;

                    if(m[42][4].destino.y<32)
                     {
                       m[42][4].destino.y+= 9;
                       m[43][7].destino.y+= 111*3;
                     }
                    if(m[42][5].destino.y<32)
                     {
                       m[42][5].destino.y+= 9;
                       m[43][8].destino.y+= 111*3;
                     }
                     break;}
    case UP:  {
    	//struct accion
    	//  {
    	//     unsigned int id_accion; //ACC_MOVER
    	//     unsigned int id_entidad; //identificado del elemento a mover
    	//     unsigned int mov_x; //offset x
    	//     unsigned int mov_y; //offset y
    	//  };


int columnaFelix;//columna donde se guarda la posicion actual de Felix en la matriz
if(*miIdJugador==ID_FELIX1)
	columnaFelix=4;
else
	columnaFelix=5;

	//La condicion del if la debe evaluar el Servidor de Partida antes de enviar el mensaje accion
        if(m[m[42][columnaFelix].destino.y-2][m[42][columnaFelix].destino.x].nombre!=BLOQ_ARR && (m[42][columnaFelix].destino.y-7)%9!=0 && m[42][columnaFelix].destino.y>3)
          {
        	//Simulacion de mensaje enviado por el Servidor de Partida
        	accion accion;
        	accion.id_accion=ACC_MOVER;
        	accion.id_entidad=*miIdJugador;
        	accion.mov_x=0;
        	accion.mov_y=-MOV_PIX_VERT_FELIX;
        	unsigned short int tramo=obtenerTramo(m);
        	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
          }

               break;

              }

    case DOWN: {

    	//struct accion
    	//  {
    	//     unsigned int id_accion; //ACC_MOVER
    	//     unsigned int id_entidad; //identificado del elemento a mover
    	//     unsigned int mov_x; //offset x
    	//     unsigned int mov_y; //offset y
    	//  };

    	int columnaFelix;//columna donde se guarda la posicion actual de Felix en la matriz
    	if(*miIdJugador==ID_FELIX1)
    		columnaFelix=4;
    	else
    		columnaFelix=5;

        	//La condicion del if la debe evaluar el Servidor de Partida antes de enviar el mensaje accion
        	if(m[m[42][columnaFelix].destino.y+1][m[42][columnaFelix].destino.x].nombre!=BLOQ_ARR && m[42][columnaFelix].destino.y<40 && (m[42][columnaFelix].destino.y-4)%9!=0)
              {
            	//Simulacion de mensaje enviado por el Servidor de Partida
            	accion accion;
            	accion.id_accion=ACC_MOVER;
            	accion.id_entidad=*miIdJugador;
            	accion.mov_x=0;
            	accion.mov_y=MOV_PIX_VERT_FELIX;
            	unsigned short int tramo=obtenerTramo(m);
            	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
              }

         break;
               }
    case RIGHT:{
    	//struct accion
    	//  {
    	//     unsigned int id_accion; //ACC_MOVER
    	//     unsigned int id_entidad; //identificado del elemento a mover
    	//     unsigned int mov_x; //offset x
    	//     unsigned int mov_y; //offset y
    	//  };

    	int columnaFelix;//columna donde se guarda la posicion actual de Felix en la matriz
    	if(*miIdJugador==ID_FELIX1)
    		columnaFelix=4;
    	else
    		columnaFelix=5;

        	//La condicion del if la debe evaluar el Servidor de Partida antes de enviar el mensaje accion
            if(m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x+1].nombre!=BLOQ_DER && m[42][columnaFelix].destino.x<8)
              {
            	//Simulacion de mensaje enviado por el Servidor de Partida
            	accion accion;
            	accion.id_accion=ACC_MOVER;
            	accion.id_entidad=*miIdJugador;
            	accion.mov_x=MOV_PIX_HOR_FELIX;
            	accion.mov_y=0;
            	unsigned short int tramo=obtenerTramo(m);
            	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
              }

                break;
               }
    case LEFT: {
    	//struct accion
    	//  {
    	//     unsigned int id_accion; //ACC_MOVER
    	//     unsigned int id_entidad; //identificado del elemento a mover
    	//     unsigned int mov_x; //offset x
    	//     unsigned int mov_y; //offset y
    	//  };
    	int columnaFelix;//columna donde se guarda la posicion actual de Felix en la matriz
    	if(*miIdJugador==ID_FELIX1)
    		columnaFelix=4;
    	else
    		columnaFelix=5;

        	//La condicion del if la debe evaluar el Servidor de Partida antes de enviar el mensaje accion
            if(m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x-1].nombre!=BLOQ_DER && m[42][columnaFelix].destino.x>0)
              {
            	//Simulacion de mensaje enviado por el Servidor de Partida
            	accion accion;
            	accion.id_accion=ACC_MOVER;
            	accion.id_entidad=*miIdJugador;
            	accion.mov_x=-MOV_PIX_HOR_FELIX;
            	accion.mov_y=0;
            	unsigned short int tramo=obtenerTramo(m);
            	procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
              }


                break;
               }
    case REPARAR: {
    	int columnaFelix;//columna donde se guarda la posicion actual de Felix en la matriz
    	if(*miIdJugador==ID_FELIX1)
    		columnaFelix=4;
    	else
    		columnaFelix=5;

    	int columnaVidrioFelix;
    	if(*miIdJugador==ID_FELIX1)//columna donde se guarda el vidrio actual en el que esta Felix en la matriz
    		columnaVidrioFelix=7;
    	else
    		columnaVidrioFelix=8;

                //La condicion if la evaluará el Servidor de Partida antes de enviar el mensaje de reparar elemento, e incrementar puntaje
                if(m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x].nombre==VIDRIO_ROTO1 || m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x].nombre==VIDRIO_ROTO2 || m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x].nombre==VIDRIO_ROTO3 || m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x].nombre==VIDRIO_ROTO4)
                 {
                  //m[m[42][4].destino.y-1][m[42][4].destino.x].nombre=VIDRIO_SANO;

                	//Simulo recibir la accion ACC_REPARAR del Servidor de Partida
                	accion accion;
                	unsigned short int tramo=obtenerTramo(m);
                    accion.id_accion=ACC_REPARAR;
                    accion.id_entidad=m[42][columnaVidrioFelix].destino.x+5;
                    accion.mov_x=0;
                    accion.mov_y=0;
                    procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);

                  //Simulo recibir la accion ACC_ACT_PUNT del Servidor de Partida
                    tramo=0;
                    accion.id_accion=ACC_ACT_PUNT;
                    accion.id_entidad=*miIdJugador;
                    accion.mov_x=100;
                    accion.mov_y=0;
                    procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
                 }
                else
                 if(m[m[42][columnaFelix].destino.y][m[42][columnaFelix].destino.x].nombre==VIDRIO_ROTO1 || m[m[42][columnaFelix].destino.y][m[42][columnaFelix].destino.x].nombre==VIDRIO_ROTO2 || m[m[42][columnaFelix].destino.y][m[42][columnaFelix].destino.x].nombre==VIDRIO_ROTO3 || m[m[42][columnaFelix].destino.y][m[42][columnaFelix].destino.x].nombre==VIDRIO_ROTO4)
                    {

                     //m[m[42][4].destino.y][m[42][4].destino.x].nombre=VIDRIO_SANO;

                 	//Simulo recibir la accion ACC_REPARAR del Servidor de Partida
                 	accion accion;
                 	unsigned short int tramo=obtenerTramo(m);
                     accion.id_accion=ACC_REPARAR;
                     accion.id_entidad=m[42][columnaVidrioFelix].destino.x;
                     accion.mov_x=0;
                     accion.mov_y=0;
                     procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);

                   //Simulo recibir la accion ACC_ACT_PUNT del Servidor de Partida
                     tramo=0;
                     accion.id_accion=ACC_ACT_PUNT;
                     accion.id_entidad=*miIdJugador;
                     accion.mov_x=3;
                     accion.mov_y=0;
                     procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
                    }
                 else
                if(m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x].nombre==VENT_CENT_ROTA)
                 {
                  //m[m[42][4].destino.y-1][m[42][4].destino.x].nombre=VENT_CENT;
                 	//Simulo recibir la accion ACC_REPARAR del Servidor de Partida
                 	accion accion;
                 	unsigned short int tramo=obtenerTramo(m);
                     accion.id_accion=ACC_REPARAR;
                     accion.id_entidad=m[42][columnaVidrioFelix].destino.x+5;
                     accion.mov_x=0;
                     accion.mov_y=0;
                     procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);

                   //Simulo recibir la accion ACC_ACT_PUNT del Servidor de Partida
                     tramo=0;
                     accion.id_accion=ACC_ACT_PUNT;
                     accion.id_entidad=*miIdJugador;
                     accion.mov_x=200;
                     accion.mov_y=0;
                     procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
                 }
                else
                if(m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x].nombre==PUERTA_ROTA1 || m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x].nombre==PUERTA_ROTA2 || m[m[42][columnaFelix].destino.y-1][m[42][columnaFelix].destino.x].nombre==PUERTA_ROTA3)
                 {
                  //m[m[42][4].destino.y-1][m[42][4].destino.x].nombre=PUERTA;
                   	//Simulo recibir la accion ACC_REPARAR del Servidor de Partida
                     	accion accion;
                     	unsigned short int tramo=obtenerTramo(m);
                         accion.id_accion=ACC_REPARAR;
                         accion.id_entidad=m[42][columnaVidrioFelix].destino.x+5;
                         accion.mov_x=0;
                         accion.mov_y=0;
                         procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);

                       //Simulo recibir la accion ACC_ACT_PUNT del Servidor de Partida
                         tramo=0;
                         accion.id_accion=ACC_ACT_PUNT;
                         accion.id_entidad=*miIdJugador;
                         accion.mov_x=1;
                         accion.mov_y=0;
                         procesarAccion(accion, tramo, m,estoyVivo,miIdJugador,miNombre);
                 }

               break;
               }
 }
  }

}

//Procesa una accion recibida del Servidor de Partida
void procesarAccion(accion accion, unsigned short int tramo, destinoSprite m[51][10],bool *estoyVivo, unsigned short int *miIdJugador,char miNombre[10])
{

//Estructura utilizada en el protocolo de comunicacion con el Servidor de Partida
//struct accion
//  {
//     unsigned int id_accion; //Que accion se hace referencia
//     unsigned int id_entidad; //A que elemento afecta directamente
//     unsigned int mov_x; //Para la accion Mover, offset x
//     unsigned int mov_y; //Para la accion Mover, offset y
//  };

//ids Acciones
//#define ACC_MOVER          1
//#define ACC_REPARAR        2
//#define ACC_ESCAPE         3
//#define ACC_MORIR          4
//#define ACC_TERM_PART      5
//#define ACC_REST_VIDA      6
//#define ACC_ACT_PUNT       7
//#define ACC_ACT_RANK       8
//#define ACC_INIT_NIVEL     9
//#define ACC_INIT_TRAM      10
//#define ACC_FIN_NIVEL		 11
//#define ACC_CREAR_TORTA    12
//#define ACC_ELIM_TORTA     13
//#define ACC_CREAR_AVE      14
//#define ACC_ELIM_AVE       15
//#define ACC_CREAR_LAD      16
//#define ACC_ELIM_LAD       17
//#define ACC_LANZAR_LAD	 18
//#define ACC_INIT_PARTIDA   19
//#define ACC_CONSUMIR_TORTA 20

//ids Entidades
//#define ID_VIDRIO_INI  0
//#define ID_VIDRIO_CANT 30
//#define ID_BLOQUEO_INI  30
//#define ID_BLOQUEO_CANT 22
//#define ID_RALPH     52
//#define ID_FELIX1    53
//#define ID_FELIX2    54
//#define ID_PALOMA    55
//#define ID_TORTA     56
//#define ID_LADRILLO_INI  57
//#define ID_LADRILLO_CANT 5

switch (accion.id_accion)
      {
       case ACC_MOVER:
       	moverElemento(accion, tramo,m,miIdJugador);
              break;
       case ACC_REPARAR: //alguno de los 2 jugadores repara una ventana
    	repararElemento(accion,tramo,m);
              break;
       case ACC_ESCAPE://respuesta a la presion de la tecla de Escape
       	salirTorneo(accion,m);
              break;
       case ACC_MORIR://murio alguno de los 2 jugadores (perdio las 3 vidas)
       	perderPartida(accion,m,estoyVivo,miIdJugador);
              break;
       case ACC_TERM_PART://los 2 jugadores murieron (perdieron las 3 vidas)
        terminarPartida();
              break;
       case ACC_REST_VIDA://alguno de los 2 jugadores pierde una vida
       	restarVida(accion,m);
              break;
       case ACC_ACT_PUNT://incrementar puntaje de algun jugador
       	actualizarPuntaje(accion,m);
              break;
       case ACC_ACT_RANK://actualiza el ranking de uno de los jugadores
        actualizarRanking(accion,m);
              break;
       case ACC_INIT_NIVEL://se recibe nro nivel
        inicializarNivel(accion,m);
              break;
       case ACC_INIT_TRAM: //se recibe numero de tramo y semilla para sorteos
    	 inicializarTramo(accion,m);
              break;
       case ACC_FIN_NIVEL:
       	incrementarNivel(m);  //Pasar al siguiente nivel
              break;
       case ACC_CREAR_TORTA:
    	 crearTorta(accion,tramo,m);
              break;
       case ACC_ELIM_TORTA:
       	 eliminarTorta(m);
              break;
       case ACC_CREAR_AVE:
         crearAve(accion,m);
              break;
       case ACC_ELIM_AVE:
    	 eliminarAve(m);
              break;
       case ACC_CREAR_LAD:
       	crearLadrillo(accion,m);
              break;
       case ACC_ELIM_LAD:
       	eliminarLadrillo(accion,m);
              break;
       case ACC_LANZAR_LAD:
       	//void lanzarLadrillo(accion accion);
              break;
       case ACC_INIT_PARTIDA:
       	inicializarPartida(accion,m,miIdJugador,miNombre);
              break;
       case ACC_CONSUMIR_TORTA:
       	//void consumirTorta(accion accion);
              break;
       case ACC_FIN_TRAM:
       	finTramo(accion,m);
              break;
      }
}

void moverElemento(accion accion, unsigned short int tramo,destinoSprite m[53][10],unsigned short int *miIdJugador)
{
	//struct accion
	//  {
	//     unsigned int id_accion; //ACC_MOVER
	//     unsigned int id_entidad; //identificador del elemento a mover
	//     unsigned int mov_x; //offset x
	//     unsigned int mov_y; //offset y
	//  };
	//Obtengo la coordenada dentro de la matriz del elemento a mover
	SDL_Rect coordenada=idEntidadToXy(accion.id_entidad, tramo);
	//Incremento la coordenada en x y la coordenada en y del elemento
    m[coordenada.x][coordenada.y].destino.x+=accion.mov_x;
    m[coordenada.x][coordenada.y].destino.y+=accion.mov_y;

    if(accion.id_entidad==ID_FELIX1 || accion.id_entidad==ID_FELIX2)
    {

    	        int columnaFelix;//columna donde se guarda la posicion actual de Felix en la matriz
    	    	if(*miIdJugador==ID_FELIX1)
    	    		columnaFelix=4;
    	    	else
    	    		columnaFelix=5;

    	    	int columnaVidrioFelix;
    	    	if(*miIdJugador==ID_FELIX1)//columna donde se guarda el vidrio actual en el que esta Felix en la matriz
    	    		columnaVidrioFelix=7;
    	    	else
    	    		columnaVidrioFelix=8;

    	    	int columnaSpriteFelix;
    	    	if(*miIdJugador==ID_FELIX1)//columna donde se guardan los datos del Sprite de Felix
    	    		columnaSpriteFelix=0;
    	    	else
    	    		columnaSpriteFelix=1;

    	if(accion.mov_x>0)//derecha
    	{
    	 m[42][columnaVidrioFelix].destino.x+= 1; //IDVidrio en el que esta Felix 1 dentro de la matriz
    	 m[42][columnaFelix].destino.x+= 2;//Columna donde esta Felix 1 en la matriz

         //Bajo la posicion en pantalla si estoy en la puerta
        if(m[42][columnaFelix].destino.x== 4 && m[42][columnaFelix].destino.y== 40)
          m[43][columnaSpriteFelix].destino.y= 419+30;
        else
          //Bajo la posicion en pantalla si estoy en la ventana central
        if(m[42][columnaFelix].destino.x== 4 && m[42][columnaFelix].destino.y== 37)
          m[43][columnaSpriteFelix].destino.y= 308+10;
        else
          m[43][columnaSpriteFelix].destino.y= 419-111*((5-tramo)*10+tramo-1-m[42][columnaFelix].destino.y)/3;

    	}
    	if(accion.mov_x<0)//izquierda
    	{
    	 m[42][columnaVidrioFelix].destino.x-= 1; //IDVidrio en el que esta Felix 1 dentro de la matriz
    	 m[42][columnaFelix].destino.x-= 2;//Columna donde esta Felix 1 en la matriz
         //Bajo la posicion en pantalla si estoy en la puerta
        if(m[42][columnaFelix].destino.x== 4 && m[42][columnaFelix].destino.y== 40)
          m[43][columnaSpriteFelix].destino.y= 419+30; //posicion en pantalla
        else
          //Bajo la posicion en pantalla si estoy en la ventana central
        if(m[42][columnaFelix].destino.x== 4 && m[42][columnaFelix].destino.y== 37)
          m[43][columnaSpriteFelix].destino.y= 308+10;
        else
          m[43][columnaSpriteFelix].destino.y= 419-111*((5-tramo)*10+tramo-1-m[42][columnaFelix].destino.y)/3;
    	}
    	if(accion.mov_y>0)//abajo
    	{
    	 m[42][columnaVidrioFelix].destino.x-= 10; //IDVidrio en el que esta Felix 1 dentro de la matriz
    	 m[42][columnaFelix].destino.y+= 3;//Fila donde esta Felix 1 en la matriz

    	 //Bajo la posicion en pantalla si estoy en la puerta
    	  if(m[42][columnaFelix].destino.x== 4 && m[42][columnaFelix].destino.y== 40)
    	     m[43][columnaSpriteFelix].destino.y= 419+30; //posicion en pantalla
    	  else
    	  //Bajo la posicion en pantalla si estoy en la ventana central
    	  if(m[42][columnaFelix].destino.x== 4 && m[42][columnaFelix].destino.y== 37)
    	    m[43][columnaSpriteFelix].destino.y= 308+10;
    	  else
    	    m[43][columnaSpriteFelix].destino.y= 419-111*((5-tramo)*10+tramo-1-m[42][columnaFelix].destino.y)/3;
    	}
    	if(accion.mov_y<0)//arriba
    	{
    	 m[42][columnaVidrioFelix].destino.x+= 10; //IDVidrio en el que esta Felix 1 dentro de la matriz
    	 m[42][columnaFelix].destino.y-= 3;//Fila donde esta Felix 1 en la matriz
    	 //Bajo la posicion en pantalla si estoy en la ventana central
    	 if(m[42][columnaFelix].destino.x== 4 && m[42][columnaFelix].destino.y== 37)
    	   m[43][columnaSpriteFelix].destino.y= 308+10;
    	 else
    	   m[43][columnaSpriteFelix].destino.y= 419-111*((5-tramo)*10+tramo-1-m[42][columnaFelix].destino.y)/3;

    	}



    }
}

void repararElemento(accion accion,unsigned short int tramo,destinoSprite m[53][10])
{
	//Obtengo la coordenada dentro de la matriz del vidrio a reparar
	SDL_Rect coordenada=idEntidadToXy(accion.id_entidad, tramo);
	//Reparo el elemento
	switch (m[coordenada.x][coordenada.y].nombre)
	{
	case VIDRIO_ROTO1:
		 m[coordenada.x][coordenada.y].nombre=VIDRIO_SANO;
		break;
	case VIDRIO_ROTO2:
		 m[coordenada.x][coordenada.y].nombre=VIDRIO_SANO;
		break;
	case VIDRIO_ROTO3:
		 m[coordenada.x][coordenada.y].nombre=VIDRIO_SANO;
		break;
	case VIDRIO_ROTO4:
		 m[coordenada.x][coordenada.y].nombre=VIDRIO_SANO;
		break;
	case VENT_CENT_ROTA:
		 m[coordenada.x][coordenada.y].nombre=VENT_CENT;
		break;
	case PUERTA_ROTA1:
		 m[coordenada.x][coordenada.y].nombre=PUERTA;
		break;
	case PUERTA_ROTA2:
		 m[coordenada.x][coordenada.y].nombre=PUERTA;
		break;
	case PUERTA_ROTA3:
		 m[coordenada.x][coordenada.y].nombre=PUERTA;
		break;
	}


	/////Me fijo si el tramo esta completo
	///Lo tiene que hacer el Servidor de Partida y luego enviar ACC_FIN_TRAM
    bool completo=true;
    //Recorro todos los vidrios
	for(unsigned short int idVidrio=ID_VIDRIO_INI; idVidrio<ID_VIDRIO_CANT; idVidrio++){

		/* Me posiciono en el vidrio seleccionado sobre la matriz. */
		coordenada=idEntidadToXy(idVidrio, tramo);

		/* Pregunto por el estado */
		if(m[coordenada.x][coordenada.y].nombre!=VIDRIO_SANO)
		 completo=false;
	}
if(completo==true)
{
	//Simulacion recibir un mensaje ACC_FIN_TRAM del Servidor de Partida
	accion.id_accion=ACC_FIN_TRAM;
	//accion.id_entidad=ID_FELIX1; //Jugador 1
	//accion.mov_x=1; //Ranking 1
	procesarAccion(accion, tramo, m,0,0,0);
}


}


void salirTorneo(accion accion,destinoSprite m[53][10])
 {
  SDL_Quit();
  exit(1);
 }

 //Pierde la partida el jugador luego de recibir el mensaje ACC_MORIR del Servidor de Partida
 // Esto se debe a que perdi� las 3 vidas
void perderPartida(accion accion,destinoSprite m[53][10],bool *estoyVivo,unsigned short int *miIdJugador)
{

	   unsigned short int tramo=0;
	   SDL_Rect coordenada1=idEntidadToXy(accion.id_entidad, tramo);
	   //Borro campo nombre para que no se dibuje
	    m[coordenada1.x][coordenada1.y].nombre=VACIO;
        if(accion.id_entidad==*miIdJugador)
	      *estoyVivo=false;

 //Borro campo nombre para que no se dibuje

//Simulacion recibir un mensaje ACC_TERM_PART debido a que los 2 jugadores murieron
 if(m[43][0].nombre==VACIO && m[43][1].nombre==VACIO)
   {
     //TODO: mostrar mensaje "esperando nuevo rival"
     //      permitir salir con Escape
   }
}

void terminarPartida()
{

}
//Resto una vida al jugador luego de recibir el mensaje ACC_REST_VIDA del Servidor de Partida
void restarVida(accion accion,destinoSprite m[53][10])
{

	unsigned char vidas;
	if(accion.id_entidad==ID_FELIX1)
	{
		vidas=obtenerVidas(JUGADOR1,m);
		decrementarVidas(&vidas);
		cargarVidas(vidas,JUGADOR1,m);
	}
	else
	{
		vidas=obtenerVidas(JUGADOR2,m);
		decrementarVidas(&vidas);
		cargarVidas(vidas,JUGADOR2,m);
	}
}

//Actualizo el puntaje del jugador luego de recibir el mensaje ACC_ACT_PUNT del Servidor de Partida
void actualizarPuntaje(accion accion,destinoSprite m[53][10])
{

	string puntaje;
	if(accion.id_entidad==ID_FELIX1)
	{
		puntaje=obtenerPuntaje(JUGADOR1,m);
		incrementarPuntaje(&puntaje,accion.mov_x);
		cargarPuntaje(puntaje,JUGADOR1,m);
	}
	else
	{
		puntaje=obtenerPuntaje(JUGADOR2,m);
		incrementarPuntaje(&puntaje,accion.mov_x);
		cargarPuntaje(puntaje,JUGADOR2,m);
	}
}


// Cargo el puntaje del Jugador en la matriz //////////////////////////
void cargarPuntaje(string punt, unsigned short int jugador, destinoSprite m[51][10])
{
if(jugador==JUGADOR1) //Jugador 1
{
 for (unsigned short int j=0;j<7;j++) //maximo 7 digitos
 m[45][j].nombre=obtenerIdCaracter(1,punt[j]);
 for(unsigned short int j=0; j<7;j+=1)
   {
    m[45][j].destino.x= 114+17*j; m[45][j].destino.y=60;
   }
}
else //Jugador 2
{
 for (unsigned short int j=0;j<7;j++) //maximo 7 digitos
   m[47][j].nombre=obtenerIdCaracter(2,punt[j]);
 for(unsigned short int j=0; j<7;j+=1)
   {
    m[47][j].destino.x= 570+17*j; m[47][j].destino.y=60;
   }
}
}

// Incremento el puntaje del jugador ///////////////////////////
void incrementarPuntaje(string *puntaje,unsigned char puntajeVidrioReparado)
{
unsigned short int bonus=puntajeVidrioReparado;
unsigned short int p;
string aux=*puntaje;
p=atoi(aux.c_str())+bonus;

stringstream stream;
stream << p;
aux = stream.str();

string aux2="";
for(unsigned short int i=0;i<(7-aux.size());i++)
  aux2+="0";
aux2+=aux;

 *puntaje=aux2;
}

// Obtengo el puntaje del jugador ////////////////////////////
string obtenerPuntaje(unsigned short int jugador,destinoSprite m[53][10])
{
string puntaje="";

if(jugador==JUGADOR1) //Jugador 1
{
 for (unsigned short int j=0;j<7;j++)
  puntaje+=obtenerCaracter(m[45][j].nombre);

}
else //Jugador 2
{
 for (unsigned short int j=0;j<7;j++)
  puntaje+=obtenerCaracter(m[47][j].nombre);
}
return puntaje;
}
void actualizarRanking(accion accion,destinoSprite m[53][10])
{
	if(accion.id_entidad==ID_FELIX1)
	{
	 //Ranking del 1 al 99
	 m[50][0].nombre=obtenerIdNumero(accion.mov_x/10);//decenas
	 m[50][0].destino.x=313;m[50][0].destino.y=60;
	 m[50][1].nombre=obtenerIdNumero(accion.mov_x%10);//unidades
	 m[50][1].destino.x=331;m[50][1].destino.y=60;
	}
	else
	{
	 //Ranking del 1 al 99
	 m[51][0].nombre=obtenerIdNumero(accion.mov_x/10);//decenas
	 m[51][0].destino.x=508;m[51][0].destino.y=60;
	 m[51][1].nombre=obtenerIdNumero(accion.mov_x%10);//unidades
	 m[51][1].destino.x=526;m[51][1].destino.y=60;
	}
}
unsigned int obtenerNivel(destinoSprite m[53][10])
{
    unsigned int nivel;
    //Niveles del 1 al 99
    nivel=obtenerNumero(m[52][0].nombre)*10+obtenerNumero(m[52][1].nombre);
    return nivel;
}
unsigned int obtenerNumero(unsigned char letra)
{

    switch (letra)
                {
                 case CERO:  return CONST_CERO; break;
                 case UNO:  return CONST_UNO; break;
                 case DOS:  return CONST_DOS; break;
                 case TRES:  return CONST_TRES; break;
                 case CUATRO:  return CONST_CUATRO; break;
                 case CINCO:  return CONST_CINCO; break;
                 case SEIS:  return CONST_SEIS; break;
                 case SIETE:  return CONST_SIETE; break;
                 case OCHO:  return CONST_OCHO; break;
                 case NUEVE:  return CONST_NUEVE; break;
                }
    return VACIO;

}
void incrementarNivel(destinoSprite m[53][10])
{
   unsigned int nivel=obtenerNivel(m);
   nivel++;
   m[52][0].nombre=obtenerIdNumero(nivel/10);//decenas
   m[52][1].nombre=obtenerIdNumero(nivel%10);//unidades
}
void inicializarNivel(accion accion,destinoSprite m[53][10])
{
    //Borro estados de los vidrios y los bloqueos
    for(unsigned short int i=3; i<=41;i++)
     for(unsigned short int j=0;j<=9;j++)
      m[i][j].nombre=VACIO;

	//Niveles del 1 al 99
	m[52][0].nombre=obtenerIdNumero(accion.id_entidad/10);//decenas
	m[52][0].destino.x=382;m[52][0].destino.y=30;
	m[52][1].nombre=obtenerIdNumero(accion.id_entidad%10);//unidades
	m[52][1].destino.x=400;m[52][1].destino.y=30;

	int desde,sep;

	if(accion.id_entidad==1)//valores segun el numero de tramo en el que estoy
	{
	 desde=12;
	 sep=-111;
	}
	else
	{
	 desde=3;
	 sep=-444;
	}

	 int separacion=sep;

	//Posiciones en pantalla

	// Defino las posiciones de los Vidrios
	for(unsigned short int i=desde; i<=39;i+=3)
	   {
	    m[i][0].destino.x= 249; m[i][0].destino.y= -435+separacion; m[i][0].nombre=VIDRIO_SANO;
	    m[i+1][0].destino.x= 249; m[i+1][0].destino.y= -409+separacion; m[i+1][0].nombre=VIDRIO_SANO;

	    m[i][2].destino.x= 319; m[i][2].destino.y= -435+separacion; m[i][2].nombre=VIDRIO_SANO;
	    m[i+1][2].destino.x= 319; m[i+1][2].destino.y= -409+separacion; m[i+1][2].nombre=VIDRIO_SANO;

	    m[i][4].destino.x= 389; m[i][4].destino.y= -435+separacion; m[i][4].nombre=VIDRIO_SANO;
	    m[i+1][4].destino.x= 389; m[i+1][4].destino.y= -409+separacion; m[i+1][4].nombre=VIDRIO_SANO;

	    m[i][6].destino.x= 459; m[i][6].destino.y= -435+separacion; m[i][6].nombre=VIDRIO_SANO;
	    m[i+1][6].destino.x= 459; m[i+1][6].destino.y= -409+separacion; m[i+1][6].nombre=VIDRIO_SANO;

	    m[i][8].destino.x= 529; m[i][8].destino.y= -435+separacion; m[i][8].nombre=VIDRIO_SANO;
	    m[i+1][8].destino.x= 529; m[i+1][8].destino.y= -409+separacion; m[i+1][8].nombre=VIDRIO_SANO;

	    separacion+=111;
	  }


	//Defino posicion de la puerta y la ventana central
	m[39][4].destino.x= 360; m[39][4].destino.y= 405;
	m[36][4].destino.x= 359; m[36][4].destino.y= 332;


	//sortearVidrios(nivel,m);

	// Defino las posiciones de los bloqueos
	separacion=sep+111;
	for(unsigned short int i=(desde+3); i<=39;i+=3)
	   {

	   m[i-1][0].destino.x= 236; m[i-1][0].destino.y= -473+separacion;
	   m[i][1].destino.x= 280; m[i][1].destino.y= -448+separacion;

	   m[i-1][2].destino.x= 306; m[i-1][2].destino.y= -473+separacion;
	   m[i][3].destino.x= 350; m[i][3].destino.y= -448+separacion;

	   m[i-1][4].destino.x= 376; m[i-1][4].destino.y= -473+separacion;
	   m[i][5].destino.x= 420; m[i][5].destino.y= -448+separacion;

	   m[i-1][6].destino.x= 446; m[i-1][6].destino.y= -473+separacion;
	   m[i][7].destino.x= 490; m[i][7].destino.y= -448+separacion;

	   m[i-1][8].destino.x= 516; m[i-1][8].destino.y= -473+separacion;

	   separacion+=111;
	  }

	//sortearBloqueos("1", m);

	m[38][5].nombre=VACIO;
	m[41][5].nombre=VACIO;

	m[37][3].nombre=VACIO;
	m[36][5].nombre=VACIO;

	m[38][4].nombre=VACIO;
	m[40][3].nombre=VACIO;
	m[39][5].nombre=VACIO;

	m[40][4].nombre=BARRA_INF;
	m[40][4].destino.x= 109; m[40][4].destino.y=533;

	m[0][0].nombre=EDIF_AZOTEA;
	m[0][0].destino.x= 189; m[0][0].destino.y= -1216;

	m[0][1].nombre=EDIF_TRAMO;
	m[0][1].destino.x= 189; m[0][1].destino.y= -904;

	if(accion.id_entidad==1)
	{
	 m[0][0].destino.x= 189; m[0][0].destino.y= -883;
	 m[0][1].nombre=VACIO;
	}

	m[0][2].nombre=EDIF_TRAMO;
	m[0][2].destino.x= 189; m[0][2].destino.y= -571;

	m[0][3].nombre=EDIF_TRAMO;
	m[0][3].destino.x= 189; m[0][3].destino.y= -238;

	m[0][4].nombre=PASTO;
	m[0][4].destino.x= 109; m[0][4].destino.y= 508;

	m[0][5].nombre=EDIF_PLNT_BAJA;
	m[0][5].destino.x= 189; m[0][5].destino.y= 94;

	m[0][6].nombre=MACETA;
	m[0][6].destino.x= 253; m[0][6].destino.y= 502;

	m[0][7].nombre=MACETA;
	m[0][7].destino.x= 464; m[0][7].destino.y= 502;

	m[42][0].nombre=PANEL_SUP;
	m[42][0].destino.x= 0; m[42][0].destino.y= 0;

	m[42][1].nombre=BANDA_NEGRA;
	m[42][1].destino.x= 0; m[42][1].destino.y=537;

	m[42][2].nombre=BARRA_SUP;
	m[42][2].destino.x= 110; m[42][2].destino.y=86;

	m[42][3].nombre=BARRA_SUP;
	m[42][3].destino.x= 110; m[42][3].destino.y=80;

	//Posicion inicial de Felix 1 en la pantalla
	m[43][0].nombre=FELIX1;
	m[43][0].destino.x= 228; m[43][0].destino.y=419;

	//Posicion inicial de Felix 1 dentro de la matriz
	m[42][4].destino.x= 0; m[42][4].destino.y=40;

	//IDVidrio en el que esta Felix 1 dentro de la matriz
	m[42][7].destino.x= 0;

	//Posicion inicial de Felix 2 en la pantalla
	m[43][1].nombre=FELIX2;
	m[43][1].destino.x= 512; m[43][1].destino.y=419;

	//IDVidrio en el que esta Felix 2 dentro de la matriz
	m[42][8].destino.x= 4;

	//Posicion inicial de Felix 2 dentro de la matriz
	m[42][5].destino.x= 8; m[42][5].destino.y=40;

	//Posicion inicial de Ralph
	m[43][2].nombre=RALPH;
	m[43][2].destino.x= 228; m[43][2].destino.y=90;


	//Cargo puntaje inicial de los jugadores//////////////////////////
    if(obtenerNivel(m)==1)
    {
     string puntaje="0000000";
    cargarPuntaje(puntaje, JUGADOR1, m);

    puntaje="0000000";
    cargarPuntaje(puntaje, JUGADOR2, m);

    //Cargo vidas iniciales de los jugadores//////////////////////////
    unsigned char vidas=TRES;
    cargarVidas(vidas, JUGADOR1, m);

    cargarVidas(vidas, JUGADOR2, m);
    }


	//Cargo el ranking de los jugadores//////////////////////////
	/*int ranking=0;
	cargarRanking(ranking, JUGADOR1, m);

	cargarRanking(ranking, JUGADOR2, m);*/

}
void inicializarTramo(accion accion,destinoSprite m[53][10])
{
 //Sorteo el estado de los bloqueos y vidrios utilizando la misma semilla que utiliza el Servidor de Partida
	//accion.id_accion=ACC_INIT_TRAM;
	//accion.id_entidad=1; //nro de tramo
	//accion.mov_x=time(NULL); //Utilizo la hora del sistema como semilla : #include <ctime>
							  //srand((unsigned)ctime(NULL));

	srand(accion.mov_x);
	accion.mov_y=1; //Cantidad de bloqueos a quitar
	sortearVidrios(accion,m);
	sortearBloqueos(accion,m);

    //Posicion inicial de Felix 1 en la pantalla
    m[43][0].nombre=FELIX1;
    m[43][0].destino.x= 228; m[43][0].destino.y=419;

    //Posicion inicial de Felix 1 dentro de la matriz
    m[42][4].destino.x= 0; m[42][4].destino.y=40-(obtenerTramo(m)-1)*9;

    //IDVidrio en el que esta Felix 1 dentro de la matriz
    m[42][7].destino.x= 0;

    //Posicion inicial de Felix 2 en la pantalla
    m[43][1].nombre=FELIX2;
    m[43][1].destino.x= 512; m[43][1].destino.y=419;

    //Posicion inicial de Felix 2 dentro de la matriz
    m[42][5].destino.x= 8; m[42][5].destino.y=40-(obtenerTramo(m)-1)*9;

    //IDVidrio en el que esta Felix 2 dentro de la matriz
    m[42][8].destino.x= 4;


}
//Sorteo estado de los vidrios en la matriz /////////////////////////////////////////
void sortearVidrios(accion accion,destinoSprite m[53][10])
 {
	    SDL_Rect coordenada;
	    //Comienzo recorriendo todos los vidrios
		for(unsigned short int idVidrio=ID_VIDRIO_INI; idVidrio<ID_VIDRIO_CANT; idVidrio++){
			/* Sorteo el estado. */
			unsigned char estado = (unsigned char)(rand()% CANT_ESTADOS_VIDRIO);

			/* Me posiciono en el vidrio seleccionado sobre la matriz. */
			coordenada=idEntidadToXy(idVidrio, accion.id_entidad);

			/* Modifico el estado */
			switch (estado)
			       {
			        case 0:
			               m[coordenada.x][coordenada.y].nombre=VIDRIO_SANO;
			               break;
			        case 1:
			        	   m[coordenada.x][coordenada.y].nombre=VIDRIO_ROTO1;
			               break;
			        default:
			        	   m[coordenada.x][coordenada.y].nombre=VIDRIO_SANO;
			               break;
			       }

		}
		   m[37][4].nombre=VACIO;
		   m[40][4].nombre=VACIO;
		   m[39][4].nombre=PUERTA;
		   m[36][4].nombre=VENT_CENT;

}

//Cargo estado de los bloqueos en la matriz /////////////////////////////////////
void sortearBloqueos(accion accion,destinoSprite m[53][10])
  {

	    unsigned char estado;
	    SDL_Rect coordenada;

		//Defino el tipo de bloqueo a usar en este tramo, si por fila o por columna.
		unsigned char tipoBloqueo = (unsigned char)(rand()% CANT_TIPOS_BLOQ);
		//Ahora creo los bloqueos uno a uno
		for(unsigned short int idBloqueo=ID_BLOQUEO_INI; idBloqueo<=MAX_IDX_BLOQUEOS; idBloqueo++){
			//Sorteo el estado del bloqueo en proceso.
			estado = sortearEstadoBloqueo(idBloqueo, tipoBloqueo);

			//Si esta bloqueado es porque es un bloqueo activo.
			if(estado == ESTADO_BLOQ_LOCK)
				{
				//Me posiciono en el bloqueo seleccionado sobre la matriz
				coordenada=idEntidadToXy(idBloqueo, accion.id_entidad);

				//Modifico el estado a activo
				 switch (tipoBloqueo)
				                   {
				                    case TIPO_BLOQ_VERTI:
				                    	m[coordenada.x][coordenada.y].nombre=BLOQ_ARR;
				                           break;
				                    case TIPO_BLOQ_HORI:
				                    	m[coordenada.x][coordenada.y].nombre=BLOQ_DER;
				                           break;
				                   }

				}
			if(accion.id_entidad==1) //Tramo 1
			{
				   m[39][5].nombre=VACIO;
				   m[36][5].nombre=VACIO;
				   m[38][4].nombre=VACIO;
			}


		}

		//Ahora quito n bloqueos por fila o columna dependiendo del tipoBloqueo para que sea posible terminar el tramo.
		quitarBloqueosParaJugar(tipoBloqueo,m,accion);


}

/* Sortea el estado para cada bloqueo del tramo, uno a la vez. */
unsigned char sortearEstadoBloqueo(int i, unsigned char tipoBloqueo)
{
	//Tomo por defecto el estado libre.
	unsigned char estado = ESTADO_BLOQ_FREE;

	//Dependiendo del tipo de bloqueo aleatorio seleccionado veo si activo o no este bloqueo.
	if(tipoBloqueo == TIPO_BLOQ_VERTI){
		//Bloqueos por columna, solo bloquea los bloqueos verticales, identificados por el indice.
		if((i >= MIN_IDX_BLOQV_FILA1 && i<=MAX_IDX_BLOQV_FILA1) ||
		   (i >= MIN_IDX_BLOQV_FILA2 && i<=MAX_IDX_BLOQV_FILA2)   ){
			estado = ESTADO_BLOQ_LOCK;
		}
	}else{
		//Bloqueos por fila
		if((i >= MIN_IDX_BLOQH_FILA1 && i<=MAX_IDX_BLOQH_FILA1) ||
		   (i >= MIN_IDX_BLOQH_FILA2 && i<=MAX_IDX_BLOQH_FILA2) ||
		   (i >= MIN_IDX_BLOQH_FILA3 && i<=MAX_IDX_BLOQH_FILA3)   ){
			estado = ESTADO_BLOQ_LOCK;
		}
	};

	return estado;
}

/* Quita aleatoriamente la cantidad de bloqueos por fila o columna ingresada por parámetro. */
void quitarBloqueosParaJugar(unsigned char tipoBloqueo, destinoSprite m[53][10],accion accion)
{
	//Voy a eliminar de a uno, la cantidad de bloqueos ingresada por parametro.
	for(int x=CONST_CERO; x <accion.mov_y; x++)
	{
		//Me fijo si son bloqueos verticales u horizontales.
		if(tipoBloqueo == TIPO_BLOQ_VERTI)
			quitarBloqueoVertical(tipoBloqueo,m,accion);
		else
			quitarBloqueoHorizontal(tipoBloqueo,m,accion);
	}
}
/*Quita un bloqueo horizontal al azar. */
void quitarBloqueoHorizontal(unsigned char tipoBloqueo,destinoSprite m[53][10],accion accion)
{
	//#define CANT_FIL_VENTANAS 3
    //#define CANT_BLOQ_X_FIL  4		//Cantidad de bloqueos horizontales por fila por tramo.
	SDL_Rect coordenada;
	//Por cada columna en la pantalla.
		for(unsigned short int col=CONST_CERO; col< CANT_COL_VENTANAS; col++){

			//Sorteo cual de los dos bloqueos por columna voy a liberar, si de fila 1 o fila 2
			unsigned short int filaALiberar = (rand() % CANT_BLOQ_X_COL);

			//Defino el idBase del cual offsetear por fila, para saber que bloqueo liberar.
			//unsigned short int idBase = getIdBaseBloqueo(tipoBloqueo, filaALiberar);

			//Genero el id_entidad del bloqueo offseteando del minimo id para esta fila por offset que representa un salto de fila..
			int idBloqueo = ID_BLOQUEO_INI+col+filaALiberar*9;

		//Me posiciono en el bloqueo seleccionado sobre la matriz de elementos.
		coordenada=idEntidadToXy(idBloqueo,accion.id_entidad);

		//Modifico el estado a desactivado
		m[coordenada.x][coordenada.y].nombre=VACIO;
	}
}

/* Quita un bloqueo vertical al azar. */
void quitarBloqueoVertical(unsigned char tipoBloqueo,destinoSprite m[53][10],accion accion)
{
	SDL_Rect coordenada;
	//Por cada fila de bloqueos verticales.
	for(unsigned short int fil=CONST_CERO; fil< CANT_FIL_VENTANAS; fil++)
	{

		//Defino el idBase del cual offsetear por fila, para saber que bloqueo liberar.
		unsigned short int idBase = getIdBaseBloqueo(tipoBloqueo, fil);

		//Sorteo cual de los bloqueos voy a liberar, si de columna 1, columna 2, columna 3, columna 4 o columna 5
		unsigned short int columnaALiberar = (rand() % CANT_BLOQ_X_FIL);

		//Genero el id_entidad del bloqueo offseteando del minimo id para esta fila por offset que representa un salto de fila..
		int idBloqueo = idBase + columnaALiberar;

		//Me posiciono en el bloqueo seleccionado sobre la matriz de elementos.
		coordenada=idEntidadToXy(idBloqueo,accion.id_entidad);

		//Modifico el estado a desactivado
		m[coordenada.x][coordenada.y].nombre=VACIO;
	}
}
/* Trae los idEntidad base para offsetear y obtener los id de los bloqueos buscados. */
unsigned short int getIdBaseBloqueo(unsigned char tipoBloqueo, int fila)
{
	//Veo si es bloqueo horizontal o vertical.
	if(tipoBloqueo == TIPO_BLOQ_HORI)
		switch(fila){
			case CONST_CERO:
				return MIN_IDX_BLOQH_FILA1;
				break;
			case CONST_UNO:
				return MIN_IDX_BLOQH_FILA2;
				break;
			case CONST_DOS:
				return MIN_IDX_BLOQH_FILA3;
				break;
			case CONST_TRES:
				return MIN_IDX_BLOQH_FILA2;
				break;
			case CONST_CUATRO:
				return MIN_IDX_BLOQH_FILA3;
				break;
		}
	else
		switch(fila){
			case CONST_CERO:
				return MIN_IDX_BLOQV_FILA1;
				break;
			case CONST_UNO:
				return MIN_IDX_BLOQV_FILA2;
				break;
		}
	return CONST_CERO;
}



//
void crearTorta(accion accion,unsigned short int tramo,destinoSprite m[53][10])
{
	//struct accion
	//  {
	//     unsigned int id_accion; //ACC_CREAR_TORTA
	//     unsigned int id_entidad; //identificador del vidrio en donde se debe crear la torta
	//     unsigned int mov_x; //sin uso
	//     unsigned int mov_y; //sin uso
	//  };

	//Estructura utilizada para almacenar los datos de cada elemento gráfico en pantalla
	//struct destinoSprite
	// {
	//    unsigned char nombre; //Ids definidos en Define.h. Se utiliza para saber que sprite recortar en la imagen origen
	//    SDL_Rect destino; //Punto de ubicacion del elemento en pantalla
	// };

	//Obtengo la coordenada dentro de la matriz del vidrio donde se creará la torta
	SDL_Rect coordenada=idEntidadToXy(accion.id_entidad, tramo);
	//Ubico la torta sobre el vidrio indicado
	m[43][5].destino.x=m[coordenada.x][coordenada.y].destino.x;
	m[43][5].destino.y=m[coordenada.x][coordenada.y].destino.y-6;
	m[43][5].nombre=TORTA1;
}
void eliminarTorta(destinoSprite m[53][10])
{
	//struct accion
	//  {
	//     unsigned int id_accion; //ACC_CREAR_TORTA
	//     unsigned int id_entidad; //identificador del vidrio en donde se creó la torta
	//     unsigned int mov_x; //sin uso
	//     unsigned int mov_y; //sin uso
	//  };

	//Estructura utilizada para almacenar los datos de cada elemento gráfico en pantalla
	//struct destinoSprite
	// {
	//    unsigned char nombre; //Ids definidos en Define.h. Se utiliza para saber que sprite recortar en la imagen origen
	//    SDL_Rect destino; //Punto de ubicacion del elemento en pantalla
	// };

	//Borro campo nombre para que no se dibuje
	m[43][5].nombre=VACIO;

}

void crearAve(accion accion,destinoSprite m[53][10])
{
	//struct accion
	//  {
	//     unsigned int id_accion; //ACC_CREAR_AVE
	//     unsigned int id_entidad; //identificador de la paloma
	//     unsigned int mov_x; //posicion x en pixeles en pantalla
	//     unsigned int mov_y; //posicion y en pixeles en pantalla
	//  };

	//Estructura utilizada para almacenar los datos de cada elemento gráfico en pantalla
	//struct destinoSprite
	// {
	//    unsigned char nombre; //Ids definidos en Define.h. Se utiliza para saber que sprite recortar en la imagen origen
	//    SDL_Rect destino; //Punto de ubicacion del elemento en pantalla
	// };

	//Ubico la paloma en la posicion indicada en el mensaje
	m[43][6].destino.x=accion.mov_x;
	m[43][6].destino.y=accion.mov_y;
	m[43][6].nombre=PALOMA1;

}
void eliminarAve(destinoSprite m[53][10])
{
	//struct accion
	//  {
	//     unsigned int id_accion; //ACC_ELIM_AVE
	//     unsigned int id_entidad; //sin uso
	//     unsigned int mov_x; //sin uso
	//     unsigned int mov_y; //sin uso
	//  };

	//Estructura utilizada para almacenar los datos de cada elemento gráfico en pantalla
	//struct destinoSprite
	// {
	//    unsigned char nombre; //Ids definidos en Define.h. Se utiliza para saber que sprite recortar en la imagen origen
	//    SDL_Rect destino; //Punto de ubicacion del elemento en pantalla
	// };

	//Borro campo nombre para que no se dibuje
     m[43][6].nombre=VACIO;

}

void crearLadrillo(accion accion,destinoSprite m[53][10])
{
	//struct accion
	//  {
	//     unsigned int id_accion; //ACC_CREAR_LADRILLO
	//     unsigned int id_entidad; //identificador del ladrillo
	//     unsigned int mov_x; //posicion x en pixeles en pantalla
	//     unsigned int mov_y; //posicion y en pixeles en pantalla
	//  };

	//Estructura utilizada para almacenar los datos de cada elemento gráfico en pantalla
	//struct destinoSprite
	// {
	//    unsigned char nombre; //Ids definidos en Define.h. Se utiliza para saber que sprite recortar en la imagen origen
	//    SDL_Rect destino; //Punto de ubicacion del elemento en pantalla
	// };

	   //Obtengo la coordenada dentro de la matriz del ladrillo a crear
	   unsigned short int tramo=0;
	   SDL_Rect coordenada=idEntidadToXy(accion.id_entidad, tramo);
	   //Ubico el ladrillo en la posicion indicada en el mensaje
	    m[coordenada.x][coordenada.y].destino.x=accion.mov_x;
	    m[coordenada.x][coordenada.y].destino.y=accion.mov_y;
	    m[coordenada.x][coordenada.y].nombre=LADRILLO1;
}
void eliminarLadrillo(accion accion,destinoSprite m[53][10])
{
	//struct accion
	//  {
	//     unsigned int id_accion; //ACC_ELIM_LADRILLO
	//     unsigned int id_entidad; //identificador del ladrillo
	//     unsigned int mov_x; //sin uso
	//     unsigned int mov_y; //sin uso
	//  };

	//Estructura utilizada para almacenar los datos de cada elemento gráfico en pantalla
	//struct destinoSprite
	// {
	//    unsigned char nombre; //Ids definidos en Define.h. Se utiliza para saber que sprite recortar en la imagen origen
	//    SDL_Rect destino; //Punto de ubicacion del elemento en pantalla
	// };

	   //Obtengo la coordenada dentro de la matriz del ladrillo a eliminar
	   unsigned short int tramo=0;
	   SDL_Rect coordenada=idEntidadToXy(accion.id_entidad, tramo);
	   //Borro campo nombre para que no se dibuje
	    m[coordenada.x][coordenada.y].nombre=VACIO;
}

//Se recibe ACC_INIT_PARTIDA del Servidor de Partida, informando que jugador somos y el nombre del otro jugador
void inicializarPartida(accion accion,destinoSprite m[53][10],unsigned short int *miIdJugador, char miNombre[10])
{
	for(unsigned short int i=0; i<=52;i++)
	 for(unsigned short int j=0;j<=9;j++)
	  m[i][j].nombre=VACIO;

	//Obtengo que jugador soy, el 1 o el 2
	*miIdJugador=accion.id_entidad;

	//Obtengo el nombre del otro jugador
	string nombreOtroJugador="";
	for (unsigned short int i=0;i<=10;i++)
		nombreOtroJugador+=accion.nombre[i];

	//Corrijo el nombre del otro jugador: Solo letras y convertir a mayusculas
	nombreOtroJugador=corregirNombre(nombreOtroJugador);


	//Obtengo el nombre mio
	string nombreMio="";
	for (unsigned short int i=0;i<=10;i++)
	  nombreMio+=miNombre[i];

	//Corrijo mi nombre: Solo letras y convertir a mayusculas
	nombreMio=corregirNombre(nombreMio);

	if(*miIdJugador==ID_FELIX1) //Jugador Local
	{
	  cargarNombre(nombreMio, JUGADOR1, m);
	  cargarNombre(nombreOtroJugador, JUGADOR2, m);
	}
	else
	{
	  cargarNombre(nombreMio, JUGADOR2, m);
	  cargarNombre(nombreOtroJugador, JUGADOR1, m);
	}


}
//// Convierte String a mayusculas ////////////////////////////////////////////
string upcase(string s1)
{
  string tmp=s1;
  for (unsigned short int i=0; i < s1.size(); i++)
     tmp.at(i) = toupper(tmp.at(i));
  return tmp;
}

///// Corrijo los caracteres del nombre (solo letras y mayusculas) ////////////////////
string corregirNombre(string nombre)
{
string correctos="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string aux="";
for (unsigned short int j=0;j<=9;j++) //maximo 10 caracteres
for (unsigned short int i=0;i<correctos.size();i++)
   if(nombre[j]==correctos[i])
        aux+=nombre[j];

//Convierto a mayusculas
string nombreMayuscula;
nombreMayuscula=upcase(aux);

return nombreMayuscula;
}

// Cargo el nombre del Jugador en la matriz //////////////////////////
void cargarNombre(string nombre, unsigned short int jugador, destinoSprite m[53][10])
{
 unsigned short int letras=nombre.size();

if(jugador==JUGADOR1) //Jugador 1
{
 for (unsigned short int j=0;j<letras;j++)
   m[44][j].nombre=obtenerIdCaracter(1,nombre[j]);
 for(unsigned short int j=0; j<=9;j+=1)
    {
     m[44][j].destino.x= 117+(220-letras*16+1)/2+16*j; m[44][j].destino.y=10;
    }
}
else //Jugador 1
{
  for (unsigned short int j=0;j<letras;j++)
    m[46][j].nombre=obtenerIdCaracter(2,nombre[j]);
  for(unsigned short int j=0; j<=9;j+=1)
   {
    m[46][j].destino.x= 465+(220-letras*16+1)/2+16*j; m[46][j].destino.y=10;
   }
}
}

void finTramo(accion accion,destinoSprite m[53][10])
{
	//if(completo==true)
	//{
		//Simulacion recibir un mensaje ACC_FIN_TRAM del Servidor de Partida
	//	accion.id_accion=ACC_FIN_TRAM;
		//accion.id_entidad=ID_FELIX1; //Jugador 1
		//accion.mov_x=1; //Ranking 1
	//	procesarAccion(accion, tramo, m,0,0,0);
	//}

    //Inicializo el nuevo tramo
if((obtenerNivel(m)==1 && obtenerTramo(m)<=2) || (obtenerNivel(m)>1 && obtenerTramo(m)<=3))
{
//Simulacion recibir un mensaje ACC_INIT_TRAM del Servidor de Partida
accion.id_accion=ACC_INIT_TRAM;
accion.id_entidad=obtenerTramo(m)+1; //nro de tramo
accion.mov_x=time(NULL); //Utilizo la hora del sistema como semilla : #include <ctime>
                         //srand((unsigned)ctime(NULL));
unsigned short int tramo=accion.id_entidad;
procesarAccion(accion, tramo, m,0,0,0);

    int scrollV=333;
    //Desplazo el dibujo verticalmente
    for(int i=0; i<=41;i++)
      for(int j=0;j<=9;j++)
         m[i][j].destino.y+=scrollV;

     if(m[42][4].destino.y>14)
      {
       m[42][4].destino.y-= 9;
       m[43][7].destino.y-= 111*3;
      }
     if(m[42][5].destino.y>14)
      {
       m[42][5].destino.y-= 9;
       m[43][8].destino.y-= 111*3;
      }
}
else //Termina el nivel
{
//Simulacion recibir un mensaje ACC_FIN_NIVEL del Servidor de Partida
accion.id_accion=ACC_FIN_NIVEL;
accion.id_entidad=0; //nro de nivel
bool vivo=true;
procesarAccion(accion, 0, m,&vivo,0,0);

//Simulacion recibir un mensaje ACC_INIT_NIVEL del Servidor de Partida
accion.id_accion=ACC_INIT_NIVEL;
accion.id_entidad=obtenerNivel(m); //nro de nivel
procesarAccion(accion, 0, m,&vivo,0,0);

//Simulacion recibir un mensaje ACC_INIT_TRAM del Servidor de Partida
accion.id_accion=ACC_INIT_TRAM;
accion.id_entidad=1; //nro de tramo
accion.mov_x=time(NULL); //Utilizo la hora del sistema como semilla : #include <ctime>
                         //srand((unsigned)ctime(NULL));
unsigned short int tramo=accion.id_entidad;
procesarAccion(accion, tramo, m,0,0,0);
}

}
// Dado un IdEntidad y el tramo actual del nivel devuelve la coordenada x(fila) y(columna)
// en donde se encuentra dentro de la matriz de entidades
SDL_Rect idEntidadToXy(unsigned short int id_entidad, unsigned short int tramo)
{
SDL_Rect coordenada;
 switch (id_entidad)
    {
     case ID_VIDRIO0:  coordenada.x=40-(tramo-1)*9; coordenada.y=0; break;
     case ID_VIDRIO1:  coordenada.x=40-(tramo-1)*9; coordenada.y=2; break;
     case ID_VIDRIO2:  if(tramo!=1){coordenada.x=40-(tramo-1)*9; coordenada.y=4;} break;
     case ID_VIDRIO3:  coordenada.x=40-(tramo-1)*9; coordenada.y=6; break;
     case ID_VIDRIO4:  coordenada.x=40-(tramo-1)*9; coordenada.y=8; break;
     case ID_VIDRIO5:  coordenada.x=39-(tramo-1)*9; coordenada.y=0; break;
     case ID_VIDRIO6:  coordenada.x=39-(tramo-1)*9; coordenada.y=2; break;
     case ID_VIDRIO7:  if(tramo!=1){coordenada.x=39-(tramo-1)*9; coordenada.y=4;} break;
     case ID_VIDRIO8:  coordenada.x=39-(tramo-1)*9; coordenada.y=6; break;
     case ID_VIDRIO9:  coordenada.x=39-(tramo-1)*9; coordenada.y=8; break;
     case ID_VIDRIO10: coordenada.x=37-(tramo-1)*9; coordenada.y=0; break;
     case ID_VIDRIO11: coordenada.x=37-(tramo-1)*9; coordenada.y=2; break;
     case ID_VIDRIO12: if(tramo!=1){coordenada.x=37-(tramo-1)*9; coordenada.y=4;} break;
     case ID_VIDRIO13: coordenada.x=37-(tramo-1)*9; coordenada.y=6; break;
     case ID_VIDRIO14: coordenada.x=37-(tramo-1)*9; coordenada.y=8; break;
     case ID_VIDRIO15: coordenada.x=36-(tramo-1)*9; coordenada.y=0; break;
     case ID_VIDRIO16: coordenada.x=36-(tramo-1)*9; coordenada.y=2; break;
     case ID_VIDRIO17: if(tramo!=1){coordenada.x=36-(tramo-1)*9; coordenada.y=4;} break;
     case ID_VIDRIO18: coordenada.x=36-(tramo-1)*9; coordenada.y=6; break;
     case ID_VIDRIO19: coordenada.x=36-(tramo-1)*9; coordenada.y=8; break;
     case ID_VIDRIO20: coordenada.x=34-(tramo-1)*9; coordenada.y=0; break;
     case ID_VIDRIO21: coordenada.x=34-(tramo-1)*9; coordenada.y=2; break;
     case ID_VIDRIO22: coordenada.x=34-(tramo-1)*9; coordenada.y=4; break;
     case ID_VIDRIO23: coordenada.x=34-(tramo-1)*9; coordenada.y=6; break;
     case ID_VIDRIO24: coordenada.x=34-(tramo-1)*9; coordenada.y=8; break;
     case ID_VIDRIO25: coordenada.x=33-(tramo-1)*9; coordenada.y=0; break;
     case ID_VIDRIO26: coordenada.x=33-(tramo-1)*9; coordenada.y=2; break;
     case ID_VIDRIO27: coordenada.x=33-(tramo-1)*9; coordenada.y=4; break;
     case ID_VIDRIO28: coordenada.x=33-(tramo-1)*9; coordenada.y=6; break;
     case ID_VIDRIO29: coordenada.x=33-(tramo-1)*9; coordenada.y=8; break;

     case ID_BLOQUEO0:  coordenada.x=39-(tramo-1)*9; coordenada.y=1; break;
     case ID_BLOQUEO1:  coordenada.x=39-(tramo-1)*9; coordenada.y=3; break;
     case ID_BLOQUEO2:  if(tramo!=1){coordenada.x=39-(tramo-1)*9; coordenada.y=5;} break;
     case ID_BLOQUEO3:  coordenada.x=39-(tramo-1)*9; coordenada.y=7; break;
     case ID_BLOQUEO4:  coordenada.x=38-(tramo-1)*9; coordenada.y=0; break;
     case ID_BLOQUEO5:  coordenada.x=38-(tramo-1)*9; coordenada.y=2; break;
     case ID_BLOQUEO6:  if(tramo!=1){coordenada.x=38-(tramo-1)*9; coordenada.y=4;} break;
     case ID_BLOQUEO7:  coordenada.x=38-(tramo-1)*9; coordenada.y=6; break;
     case ID_BLOQUEO8:  coordenada.x=38-(tramo-1)*9; coordenada.y=8; break;
     case ID_BLOQUEO9:  coordenada.x=36-(tramo-1)*9; coordenada.y=1; break;
     case ID_BLOQUEO10: coordenada.x=36-(tramo-1)*9; coordenada.y=3; break;
     case ID_BLOQUEO11: if(tramo!=1){coordenada.x=36-(tramo-1)*9; coordenada.y=5;} break;
     case ID_BLOQUEO12: coordenada.x=36-(tramo-1)*9; coordenada.y=7; break;
     case ID_BLOQUEO13: coordenada.x=35-(tramo-1)*9; coordenada.y=0; break;
     case ID_BLOQUEO14: coordenada.x=35-(tramo-1)*9; coordenada.y=2; break;
     case ID_BLOQUEO15: coordenada.x=35-(tramo-1)*9; coordenada.y=4; break;
     case ID_BLOQUEO16: coordenada.x=35-(tramo-1)*9; coordenada.y=6; break;
     case ID_BLOQUEO17: coordenada.x=35-(tramo-1)*9; coordenada.y=8; break;
     case ID_BLOQUEO18: coordenada.x=33-(tramo-1)*9; coordenada.y=1; break;
     case ID_BLOQUEO19: coordenada.x=33-(tramo-1)*9; coordenada.y=3; break;
     case ID_BLOQUEO20: coordenada.x=33-(tramo-1)*9; coordenada.y=5; break;
     case ID_BLOQUEO21: coordenada.x=33-(tramo-1)*9; coordenada.y=7; break;

     case ID_RALPH:     coordenada.x=43; coordenada.y=2; break;
     case ID_FELIX1:    coordenada.x=43; coordenada.y=0; break;
     case ID_FELIX2:    coordenada.x=43; coordenada.y=1; break;
     case ID_PALOMA:    coordenada.x=43; coordenada.y=4; break;
     case ID_TORTA:     coordenada.x=43; coordenada.y=3; break;
     case ID_LADRILLO0: coordenada.x=43; coordenada.y=5; break;
     case ID_LADRILLO1: coordenada.x=43; coordenada.y=6; break;
     case ID_LADRILLO2: coordenada.x=43; coordenada.y=7; break;
     case ID_LADRILLO3: coordenada.x=43; coordenada.y=8; break;
     case ID_LADRILLO4: coordenada.x=43; coordenada.y=9; break;

    }
return coordenada;
}
/////////////////////////// Dibuja la matriz completa //////////////////////////////
void dibujarMatriz(destinoSprite m[53][10], SDL_Surface * pant, SDL_Surface *imag1, SDL_Surface *imag2)
{

//Borro pantalla
  SDL_Rect PosScr;
  PosScr.x = 0;
  PosScr.y = 0;
  PosScr.w = pant -> w;
  PosScr.h = pant -> h;
  SDL_FillRect( pant, &PosScr, SDL_MapRGB( pant -> format, 0, 0, 0) );

//Dibujo matriz
SDL_Rect aux,aux2;
for(int i=0; i<=52;i++)
for(int j=0;j<=9;j++)
  if(m[i][j].nombre!=VACIO)
     {
     aux=obtenerOrigenSprite(m[i][j].nombre);
     aux2=m[i][j].destino;
     if(m[i][j].nombre==FELIX2)
      SDL_BlitSurface(imag2, &aux, pant, &aux2);
     else
      SDL_BlitSurface(imag1, &aux, pant, &aux2);
     }

// Actualizo la superficie principal
SDL_Flip(pant);

//Actualizo toda la superficie
SDL_UpdateRect(pant, 0, 0, 0, 0);
}

//Obtengo el tramo del edificio en donde se encuentra el nivel
unsigned short int obtenerTramo(destinoSprite m[53][10])
{
 unsigned short int tramo;
 if(m[42][4].destino.y>33)
  tramo=1;
 else
  if(m[42][4].destino.y>24)
   tramo=2;
  else
   if(m[42][4].destino.y>15)
    tramo=3;
   else
     if(m[42][4].destino.y>6)
      tramo=4;

 return tramo;
}

// Cargo el nivel //////////////////////////
void cargarNivel(string nombre, destinoSprite m[53][10])
{
/* unsigned short int letras=nombre.size();

 for (unsigned short int j=0;j<letras;j++)
   m[52][j].nombre=obtenerIdCaracter(1,nombre[j]);
 for(unsigned short int j=0; j<=9;j+=1)
    {
     m[52][j].destino.x=290+(220-letras*16+1)/2+16*j; m[52][j].destino.y=10;
    }
 */
}

unsigned char obtenerIdNumero(unsigned short int numero)
{
	switch (numero)
	       	        {
	       	         case 0:  return CERO; break;
	       	         case 1:  return UNO; break;
	       	         case 2:  return DOS; break;
	       	         case 3:  return TRES; break;
	       	         case 4:  return CUATRO; break;
	       	         case 5:  return CINCO; break;
	       	         case 6:  return SEIS; break;
	       	         case 7:  return SIETE; break;
	       	         case 8:  return OCHO; break;
	       	         case 9:  return NUEVE; break;
	       	        }
	return VACIO;
}
char obtenerCaracter(unsigned char idCaracter)
{
 switch (idCaracter)
    {
     case CERO:   return '0'; break;
     case UNO:    return '1'; break;
     case DOS:    return '2'; break;
     case TRES:   return '3'; break;
     case CUATRO: return '4'; break;
     case CINCO:  return '5'; break;
     case SEIS:   return '6'; break;
     case SIETE:  return '7'; break;
     case OCHO:   return '8'; break;
     case NUEVE:  return '9'; break;
    }
 return '0';
}

unsigned char obtenerIdCaracter(unsigned short int jugador,char letra)
{
switch (jugador)
      {
       case 1:
       	 switch (letra)
       	        {
       	         case 'A':  return A1; break;
       	         case 'B':  return B1; break;
       	         case 'C':  return C1; break;
       	         case 'D':  return D1; break;
       	         case 'E':  return E1; break;
       	         case 'F':  return F1; break;
       	         case 'G':  return G1; break;
       	         case 'H':  return H1; break;
       	         case 'I':  return I1; break;
       	         case 'J':  return J1; break;
       	         case 'K':  return K1; break;
       	         case 'L':  return L1; break;
       	         case 'M':  return M1; break;
       	         case 'N':  return N1; break;
                 case 'O':  return O1; break;
       	         case 'P':  return P1; break;
       	         case 'Q':  return Q1; break;
       	         case 'R':  return R1; break;
       	         case 'S':  return S1; break;
       	         case 'T':  return T1; break;
       	         case 'U':  return U1; break;
       	         case 'V':  return V1; break;
       	         case 'W':  return W1; break;
       	         case 'X':  return X1; break;
       	         case 'Y':  return Y1; break;
       	         case 'Z':  return Z1; break;
       	        }
              break;
       	 case 2:
       	 switch (letra)
       	 {
       	 case 'A':  return A2; break;
       	 case 'B':  return B2; break;
       	 case 'C':  return C2; break;
       	 case 'D':  return D2; break;
       	 case 'E':  return E2; break;
       	 case 'F':  return F2; break;
       	 case 'G':  return G2; break;
       	 case 'H':  return H2; break;
       	 case 'I':  return I2; break;
       	 case 'J':  return J2; break;
       	 case 'K':  return K2; break;
       	 case 'L':  return L2; break;
       	 case 'M':  return M2; break;
       	 case 'N':  return N2; break;
       	 case 'O':  return O2; break;
       	 case 'P':  return P2; break;
       	 case 'Q':  return Q2; break;
       	 case 'R':  return R2; break;
       	 case 'S':  return S2; break;
       	 case 'T':  return T2; break;
       	 case 'U':  return U2; break;
       	 case 'V':  return V2; break;
       	 case 'W':  return W2; break;
       	 case 'X':  return X2; break;
       	 case 'Y':  return Y2; break;
       	 case 'Z':  return Z2; break;
       	        }
              break;

      }

switch (letra)
       	        {
       	         case '0':  return CERO; break;
       	         case '1':  return UNO; break;
       	         case '2':  return DOS; break;
       	         case '3':  return TRES; break;
       	         case '4':  return CUATRO; break;
       	         case '5':  return CINCO; break;
       	         case '6':  return SEIS; break;
       	         case '7':  return SIETE; break;
       	         case '8':  return OCHO; break;
       	         case '9':  return NUEVE; break;
       	        }
return VACIO;
}
// Cargo las vidas del Jugador en la matriz //////////////////////////
void cargarVidas(unsigned char vidas, unsigned short int jugador, destinoSprite m[53][10])
{
if(jugador==JUGADOR1) //Jugador 1
{
  m[48][0].nombre=vidas;
  m[48][0].destino.x= 318; m[48][0].destino.y=39;
}
else //Jugador 2
{
 m[49][0].nombre=vidas;
 m[49][0].destino.x= 516; m[49][0].destino.y=39;
}
}

// Obtengo las vidas del jugador ////////////////////////////
unsigned char obtenerVidas(unsigned short int jugador,destinoSprite m[53][10])
{
unsigned char vidas;
if(jugador==JUGADOR1) //Jugador Local
{
  vidas=m[48][0].nombre;

}
else //Jugador Visitante
{
 vidas=m[49][0].nombre;
}
return vidas;
}

// Decremento las vidas del jugador ///////////////////////////
void decrementarVidas(unsigned char *vidas)
{
*vidas=*vidas-1;
}


void animarTortas(destinoSprite m[53][10])
     {
      for(int i=8; i<=41;i+=3)
       {
         if(m[i][1].nombre==TORTA1)
           m[i][1].nombre=TORTA2;
         else
            if(m[i][1].nombre==TORTA2)
              m[i][1].nombre=TORTA1;

         if(m[i][3].nombre==TORTA1)
           m[i][3].nombre=TORTA2;
         else
            if(m[i][3].nombre==TORTA2)
              m[i][3].nombre=TORTA1;

         if(m[i][5].nombre==TORTA1)
           m[i][5].nombre=TORTA2;
         else
            if(m[i][5].nombre==TORTA2)
              m[i][5].nombre=TORTA1;

         if(m[i][7].nombre==TORTA1)
           m[i][7].nombre=TORTA2;
         else
            if(m[i][7].nombre==TORTA2)
              m[i][7].nombre=TORTA1;

         if(m[i][9].nombre==TORTA1)
           m[i][9].nombre=TORTA2;
         else
            if(m[i][9].nombre==TORTA2)
              m[i][9].nombre=TORTA1;
        }
      }

///// Programa principal ////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
Config oConfig(APP_CONFIG);
 map<int, int> controles;
 //int port = oConfig.obtenerPuerto();
 std::string host = oConfig.obtenerHost();
 controles = oConfig.obtenerControles();

//Ignoro los eventos que no uso
SDL_EventState(SDL_MOUSEMOTION,SDL_IGNORE);
SDL_EventState(SDL_MOUSEBUTTONDOWN,SDL_IGNORE);
SDL_EventState(SDL_MOUSEBUTTONUP,SDL_IGNORE);
//SDL_EventState(SDL_MOUSEWHEEL,SDL_IGNORE);
SDL_EventState(SDL_KEYUP,SDL_IGNORE);
//SDL_EventState(SDL_WINDOWEVENT,SDL_IGNORE);


SDL_Surface * pantalla;
SDL_Surface *imagen1;
SDL_Surface *imagen2;
destinoSprite matriz[53][10];
unsigned short int miIdJugador=1;
bool estoyVivo=true;



if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
 cout<<"Error al inicializar"<< SDL_GetError()<<endl;
 return 1;
}

/*De esta forma me aseguro que al cerrarse el programa se cierren también todos
los subsitemas de SDL*/
atexit(SDL_Quit);

/*Inicializo el modo de video con una pantalla de 800 x 600 con 32 bytes de
profundidad de color */
pantalla = SDL_SetVideoMode(ANCHO_VENTANA, ALTO_VENTANA, 32, 0);

if (pantalla == NULL)
 {
  cout<<"Error modo de video"<< SDL_GetError()<<endl;
  return 1;
 }

//Bloqueo el uso de la superficie
SDL_LockSurface(pantalla);

// Cargo la imagen que contiene todos los sprites de Felix 1
imagen1 = IMG_Load("SpritesFelix1.bmp");

if(imagen1 == NULL)
 {
  cerr << "Error: " << SDL_GetError() << endl;
  exit(1);
 }

// Defino color transparente para la imagen
SDL_SetColorKey(imagen1, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(imagen1 -> format, 185, 243, 182));

// Convierto la imagen a formato de pantalla
SDL_Surface *tmp = imagen1;
imagen1 = SDL_DisplayFormat(tmp);
SDL_FreeSurface(tmp);

if(imagen1 == NULL)
 {
  cerr << "Error: " << SDL_GetError() << endl;
  exit(1);
 }

// Cargo la imagen que contiene todos los sprites de Felix 2
imagen2 = IMG_Load("SpritesFelix2.bmp");

if(imagen2 == NULL)
 {
  cerr << "Error: " << SDL_GetError() << endl;
  exit(1);
 }

// Defino color transparente para la imagen
SDL_SetColorKey(imagen2, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(imagen2 -> format, 185, 243, 182));

// Convierto la imagen a formato de pantalla
tmp = imagen2;
imagen2 = SDL_DisplayFormat(tmp);
SDL_FreeSurface(tmp);

if(imagen2 == NULL)
 {
  cerr << "Error: " << SDL_GetError() << endl;
  exit(1);
 }

//Desbloqueo la superficie
SDL_UnlockSurface(pantalla);


//Cargo mi nombre //////////////////////////
char miNombre[10]={'D','a','m','i','a','n'};

//Simulacion recibir un mensaje ACC_INIT_PARTIDA del Servidor de Partida
accion accion;
accion.id_accion=ACC_INIT_PARTIDA;
accion.id_entidad=ID_FELIX2;
accion.mov_x=0; //sin uso
accion.mov_y=0; //sin uso
string nom="Rival";
unsigned short int letras=nom.size();
for (unsigned short int i=0;i<letras;i++)
	accion.nombre[i]=nom[i];

unsigned short int tramo=0;
procesarAccion(accion,tramo,matriz,&estoyVivo,&miIdJugador,miNombre);


//Simulacion recibir un mensaje ACC_INIT_NIVEL del Servidor de Partida
accion.id_accion=ACC_INIT_NIVEL;
accion.id_entidad=1; //nro de nivel
bool vivo=true;
procesarAccion(accion, tramo, matriz,&vivo,&miIdJugador,miNombre);


//Simulacion recibir un mensaje ACC_INIT_TRAM del Servidor de Partida
accion.id_accion=ACC_INIT_TRAM;
accion.id_entidad=1; //nro de tramo
accion.mov_x=time(NULL); //Utilizo la hora del sistema como semilla : #include <ctime>
						 //srand((unsigned)ctime(NULL));
vivo=true;
procesarAccion(accion, tramo, matriz,&vivo,&miIdJugador,miNombre);

//Simulacion recibir un mensaje ACC_ACT_RANK del Servidor de Partida
accion.id_accion=ACC_ACT_RANK;
accion.id_entidad=ID_FELIX1; //Jugador 1
accion.mov_x=1; //Ranking 1
procesarAccion(accion, tramo, matriz,&vivo,&miIdJugador,miNombre);

accion.id_accion=ACC_ACT_RANK;
accion.id_entidad=ID_FELIX2; //Jugador 2
accion.mov_x=2; //Ranking 2
procesarAccion(accion, tramo, matriz,&vivo,&miIdJugador,miNombre);
//Realizo una pausa
//SDL_Delay(10000);

// SDLA_esperarTecla();



while(1)
{

procesarEventosSDL(matriz,controles,&estoyVivo,&miIdJugador,miNombre);
//usleep(10000);
//SDL_Delay(100);
//animarTortas(matriz);
 dibujarMatriz(matriz, pantalla, imagen1,imagen2);
 usleep(10000);
 //SDL_Delay(100);
}
 return 0;
}


////////// Devuelve la coordenada de un sprite dentro de la imagen //////////////////////
SDL_Rect obtenerOrigenSprite(unsigned char nombre)
{
 SDL_Rect origen;
switch(nombre)
{
case	VIDRIO_SANO :	origen.x = 608; origen.y = 0; origen.w = 25; origen.h = 21; break;
case	VIDRIO_ROTO1 :	origen.x = 608; origen.y = 64; origen.w = 25; origen.h = 21; break;
case	VIDRIO_ROTO2 :	origen.x = 608; origen.y = 32; origen.w = 25; origen.h = 21; break;
case	VIDRIO_ROTO3 :	origen.x = 640; origen.y = 32; origen.w = 25; origen.h = 21; break;
case	VIDRIO_ROTO4 :	origen.x = 640; origen.y = 64; origen.w = 25; origen.h = 21; break;
case	PASTO :	 		origen.x = 1024; origen.y = 1496; origen.w = 581; origen.h = 25; break;
case	EDIF_PLNT_BAJA: origen.x = 14; origen.y = 1; origen.w = 421; origen.h = 439; break;
case	EDIF_TRAMO :	origen.x = 1413; origen.y = 224; origen.w = 421; origen.h = 435; break;
case	EDIF_AZOTEA :	origen.x = 590; origen.y = 1608; origen.w = 421; origen.h = 313; break;
case	VENT_CENT :		origen.x = 456; origen.y = 104; origen.w = 81; origen.h = 73; break;
case	VENT_CENT_ROTA: origen.x = 552; origen.y = 104; origen.w = 81; origen.h = 73; break;
case	PUERTA :		origen.x = 650; origen.y = 96; origen.w = 79; origen.h = 128; break;
case	PUERTA_ROTA1 :	origen.x = 746; origen.y = 96; origen.w = 79; origen.h = 128; break;
case	PUERTA_ROTA2 :	origen.x = 842; origen.y = 96; origen.w = 79; origen.h = 128; break;
case	PUERTA_ROTA3 :	origen.x = 938; origen.y = 96; origen.w = 79; origen.h = 128; break;
case	MACETA :		origen.x = 452; origen.y = 190; origen.w = 82; origen.h = 31;  break;
case	BARRA_SUP :		origen.x = 1035; origen.y = 1956; origen.w = 581; origen.h = 4;  break;
case	PANEL_SUP :		origen.x = 1005; origen.y = 1227; origen.w = 800; origen.h = 90; break;
case	BANDA_NEGRA :	origen.x = 1005; origen.y = 1168; origen.w = 800; origen.h = 90;  break;
case	BARRA_INF :		origen.x = 1035; origen.y = 1963; origen.w = 581; origen.h = 4;  break;
case	BLOQ_ARR :		origen.x = 1840; origen.y = 0; origen.w = 51; origen.h = 13; break;
case	BLOQ_DER :		origen.x = 1984; origen.y = 11; origen.w = 9; origen.h = 69; break;
case	TORTA1 :		origen.x = 800; origen.y = 6; origen.w = 23; origen.h = 27; break;
case	TORTA2 :		origen.x = 832; origen.y = 6; origen.w = 23; origen.h = 27; break;
case	LADRILLO1 :		origen.x = 736; origen.y = 0; origen.w = 25; origen.h = 17; break;
case	LADRILLO2 :		origen.x = 770; origen.y = 0; origen.w = 25; origen.h = 17; break;
case	FELIX1 :		origen.x = 4; origen.y = 446; origen.w = 31; origen.h = 83; break;
case	FELIX2 :		origen.x = 4; origen.y = 446; origen.w = 31; origen.h = 83; break;
case	RALPH :	 		origen.x = 22; origen.y = 852; origen.w = 91; origen.h = 109; break;
case	PALOMA1 :	 	origen.x = 870; origen.y = 320; origen.w = 43; origen.h = 39; break;
case	PALOMA2 :	 	origen.x = 918; origen.y = 320; origen.w = 43; origen.h = 39; break;
case	CERO :	 		origen.x = 256; origen.y = 1936; origen.w = 15; origen.h = 15; break;
case	UNO :	  		origen.x = 274; origen.y = 1936; origen.w = 13; origen.h = 15; break;
case	DOS :			origen.x = 288; origen.y = 1936; origen.w = 15; origen.h = 15; break;
case	TRES :	 		origen.x = 304; origen.y = 1936; origen.w = 15; origen.h = 15; break;
case	CUATRO :		origen.x = 320; origen.y = 1936; origen.w = 15; origen.h = 15; break;
case	CINCO :			origen.x = 336; origen.y = 1936; origen.w = 15; origen.h = 15; break;
case	SEIS :			origen.x = 352; origen.y = 1936; origen.w = 15; origen.h = 15; break;
case	SIETE :			origen.x = 368; origen.y = 1936; origen.w = 15; origen.h = 15; break;
case	OCHO :			origen.x = 384; origen.y = 1936; origen.w = 15; origen.h = 15; break;
case	NUEVE :	 		origen.x = 400; origen.y = 1936; origen.w = 15; origen.h = 15; break;
case	A1 :	 		origen.x = 528; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	B1 :			origen.x = 544; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	C1 :			origen.x = 560; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	D1 :			origen.x = 576; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	E1 :			origen.x = 592; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	F1 :			origen.x = 608; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	G1 :			origen.x = 624; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	H1 :	 		origen.x = 640; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	I1 :			origen.x = 658; origen.y = 1984; origen.w = 13; origen.h = 15; break;
case	J1 :			origen.x = 672; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	K1 :	 		origen.x = 688; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	L1 :			origen.x = 704; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	M1 :			origen.x = 720; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	N1 :			origen.x = 736; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	O1 :	 		origen.x = 752; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	P1 :			origen.x = 768; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	Q1 :	 		origen.x = 784; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	R1 :	 		origen.x = 800; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	S1 :	 		origen.x = 816; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	T1 :	 		origen.x = 834; origen.y = 1984; origen.w = 13; origen.h = 15; break;
case	U1 :	 		origen.x = 848; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	V1 :	 		origen.x = 864; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	W1 :	 		origen.x = 880; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	X1 :	 		origen.x = 896; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	Y1 :	 		origen.x = 914; origen.y = 1984; origen.w = 13; origen.h = 15; break;
case	Z1 :	 		origen.x = 928; origen.y = 1984; origen.w = 15; origen.h = 15; break;
case	A2 :	 		origen.x = 528; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	B2 :	 		origen.x = 256; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	C2 :	 		origen.x = 560; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	D2 :			origen.x = 576; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	E2 :	 		origen.x = 592; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	F2 :	 		origen.x = 608; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	G2 :	 		origen.x = 624; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	H2 :	 		origen.x = 640; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	I2 :	 		origen.x = 658; origen.y = 2000; origen.w = 13; origen.h = 15; break;
case	J2 :	 		origen.x = 672; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	K2 :	 		origen.x = 688; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	L2 :	 		origen.x = 704; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	M2 :	 		origen.x = 720; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	N2 :	 		origen.x = 736; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	O2 :	 		origen.x = 752; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	P2 :	 		origen.x = 768; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	Q2 :	 		origen.x = 784; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	R2 :	 		origen.x = 800; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	S2 :	 		origen.x = 816; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	T2 :	 		origen.x = 834; origen.y = 2000; origen.w = 13; origen.h = 15; break;
case	U2 :	 		origen.x = 848; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	V2 :	 		origen.x = 864; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	W2 :	 		origen.x = 880; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	X2 :	 		origen.x = 896; origen.y = 2000; origen.w = 15; origen.h = 15; break;
case	Y2 :	 		origen.x = 914; origen.y = 2000; origen.w = 13; origen.h = 15; break;
case	Z2 :	 		origen.x = 928; origen.y = 2000; origen.w = 15; origen.h = 15; break;

}
 return origen;
}
